#ifndef PAGENUMBER_V2_H
#define PAGENUMBER_V2_H

#include <QString>
#include <optional>
#include <QDebug>

/**
 * @file pagenumber_v2.h
 * @brief 类型安全的页码系统 - 下一代架构
 * 
 * 设计理念：
 * 1. 用类型系统消除0-based/1-based的歧义
 * 2. 编译期检查，而非运行期调试
 * 3. 自解释代码，无需注释
 * 4. 不可变值对象，线程安全
 * 
 * @author LimeReader Team
 * @date 2025-11-04
 */

namespace PageNumberV2 {

// ============================================================================
// 核心类型：ArrayIndex（数组索引，0-based）
// ============================================================================

/**
 * @brief 数组索引类型（0-based）
 * 
 * 用途：访问QList、QVector等容器
 * 不变式：m_value >= 0
 * 
 * 示例：
 * @code
 *   QList<QImage> pages;
 *   ArrayIndex idx(0);
 *   QImage img = pages[idx.value()];
 * @endcode
 */
class ArrayIndex {
private:
    int m_value;
    
public:
    // 构造函数：强制非负
    explicit constexpr ArrayIndex(int value = 0) 
        : m_value(value < 0 ? 0 : value) {}
    
    // 访问器
    constexpr int value() const { return m_value; }
    constexpr bool isValid() const { return m_value >= 0; }
    
    // 运算符（返回新对象，保持不可变性）
    constexpr ArrayIndex next() const { return ArrayIndex(m_value + 1); }
    constexpr ArrayIndex previous() const { return ArrayIndex(m_value > 0 ? m_value - 1 : 0); }
    
    // 比较运算符
    friend constexpr bool operator==(ArrayIndex a, ArrayIndex b) { return a.m_value == b.m_value; }
    friend constexpr bool operator<(ArrayIndex a, ArrayIndex b) { return a.m_value < b.m_value; }
    friend constexpr bool operator<=(ArrayIndex a, ArrayIndex b) { return a.m_value <= b.m_value; }
    
    // 调试输出
    friend QDebug operator<<(QDebug debug, ArrayIndex idx) {
        return debug << "ArrayIndex(" << idx.m_value << ")";
    }
};

// ============================================================================
// 核心类型：PageNumber（页码，1-based）
// ============================================================================

/**
 * @brief 页码类型（1-based）
 * 
 * 用途：显示给用户，打印到PDF
 * 不变式：m_value >= 1
 * 
 * 示例：
 * @code
 *   PageNumber page(5);
 * @endcode
 */
class PageNumber {
private:
    int m_value;
    
public:
    // 构造函数：强制 >= 1
    explicit constexpr PageNumber(int value = 1) 
        : m_value(value < 1 ? 1 : value) {}
    
    // 访问器
    constexpr int value() const { return m_value; }
    constexpr bool isValid() const { return m_value >= 1; }
    
    // 类型转换（显式）
    constexpr ArrayIndex toArrayIndex() const { 
        return ArrayIndex(m_value - 1); 
    }
    
    static constexpr PageNumber fromArrayIndex(ArrayIndex idx) {
        return PageNumber(idx.value() + 1);
    }
    
    // 运算符
    constexpr PageNumber next() const { return PageNumber(m_value + 1); }
    constexpr PageNumber previous() const { return PageNumber(m_value > 1 ? m_value - 1 : 1); }
    
    // 格式化
    QString toString() const { return QString::number(m_value); }
    
    // 比较运算符
    friend constexpr bool operator==(PageNumber a, PageNumber b) { return a.m_value == b.m_value; }
    friend constexpr bool operator<(PageNumber a, PageNumber b) { return a.m_value < b.m_value; }
    friend constexpr bool operator<=(PageNumber a, PageNumber b) { return a.m_value <= b.m_value; }
    
    // 调试输出
    friend QDebug operator<<(QDebug debug, PageNumber page) {
        return debug << "PageNumber(" << page.m_value << ")";
    }
};

// ============================================================================
// 业务类型：LocalPageNumber（文件内页码）
// ============================================================================

/**
 * @brief 文件内页码（局部页码，1-based）
 * 
 * 封装：文件标识 + 页码
 * 
 * 示例：
 * @code
 *   LocalPageNumber local("file123.pdf", PageNumber(3));
 * @endcode
 */
class LocalPageNumber {
private:
    QString m_fileId;
    PageNumber m_page;
    
public:
    LocalPageNumber(const QString& fileId, PageNumber page)
        : m_fileId(fileId), m_page(page) {}
    
    QString fileId() const { return m_fileId; }
    PageNumber page() const { return m_page; }
    
    // 便捷访问
    int pageValue() const { return m_page.value(); }
    
    // 调试输出
    friend QDebug operator<<(QDebug debug, const LocalPageNumber& local) {
        return debug << "LocalPageNumber(file=" << local.m_fileId 
                     << ", page=" << local.m_page.value() << ")";
    }
};

// ============================================================================
// 业务类型：GlobalPageNumber（全局页码）
// ============================================================================

/**
 * @brief 全局页码（跨文件连续页码，1-based）
 * 
 * 封装：页码 + 总页数（用于验证和导航）
 * 
 * 示例：
 * @code
 *   GlobalPageNumber global(PageNumber(15), 100);
 *   if (global.isValid()) {
 *   }
 * @endcode
 */
class GlobalPageNumber {
private:
    PageNumber m_page;
    int m_totalPages;
    
public:
    GlobalPageNumber(PageNumber page, int totalPages)
        : m_page(page), m_totalPages(totalPages) {}
    
    PageNumber page() const { return m_page; }
    int totalPages() const { return m_totalPages; }
    
    // 便捷访问
    int pageValue() const { return m_page.value(); }
    
    // 业务逻辑
    bool isValid() const { 
        return m_page.value() >= 1 && m_page.value() <= m_totalPages; 
    }
    bool isFirstPage() const { return m_page.value() == 1; }
    bool isLastPage() const { return m_page.value() == m_totalPages; }
    bool hasNextPage() const { return m_page.value() < m_totalPages; }
    bool hasPreviousPage() const { return m_page.value() > 1; }
    
    // 导航（返回新对象）
    GlobalPageNumber next() const { 
        return GlobalPageNumber(m_page.next(), m_totalPages); 
    }
    GlobalPageNumber previous() const { 
        return GlobalPageNumber(m_page.previous(), m_totalPages); 
    }
    
    // 格式化（支持占位符）
    QString format(const QString& template_) const {
        return QString(template_)
            .replace("{page}", m_page.toString())
            .replace("{total}", QString::number(m_totalPages))
            .replace("{global}", m_page.toString());
    }
    
    // 调试输出
    friend QDebug operator<<(QDebug debug, const GlobalPageNumber& global) {
        return debug << "GlobalPageNumber(page=" << global.m_page.value() 
                     << ", total=" << global.m_totalPages << ")";
    }
};

// ============================================================================
// 工具函数：类型转换
// ============================================================================

/**
 * @brief 从数组索引创建全局页码
 * @param idx 数组索引（0-based）
 * @param startPage 文件起始全局页码（1-based）
 * @param totalPages 全局总页数
 * @return 全局页码
 * 
 * 示例：
 * @code
 *   // 第3个文件，起始页50，当前显示该文件的第2页（索引1）
 *   ArrayIndex idx(1);
 *   GlobalPageNumber global = arrayIndexToGlobal(idx, PageNumber(50), 100);
 *   // global.pageValue() == 51
 * @endcode
 */
inline GlobalPageNumber arrayIndexToGlobal(
    ArrayIndex idx, 
    PageNumber startPage, 
    int totalPages
) {
    int globalValue = startPage.value() + idx.value();
    return GlobalPageNumber(PageNumber(globalValue), totalPages);
}

/**
 * @brief 从全局页码提取数组索引
 * @param global 全局页码
 * @param startPage 文件起始全局页码
 * @return 数组索引（如果页码不在文件范围内，返回nullopt）
 * 
 * 示例：
 * @code
 *   GlobalPageNumber global(PageNumber(51), 100);
 *   auto idx = globalToArrayIndex(global, PageNumber(50));
 *   if (idx.has_value()) {
 *   }
 * @endcode
 */
inline std::optional<ArrayIndex> globalToArrayIndex(
    const GlobalPageNumber& global, 
    PageNumber startPage
) {
    int offset = global.pageValue() - startPage.value();
    if (offset < 0) {
        return std::nullopt;
    }
    return ArrayIndex(offset);
}

} // namespace PageNumberV2

// ============================================================================
// 使用示例（放在注释中，供参考）
// ============================================================================

/*

// ====== 示例1：文件内页面切换 ======

void PageView::nextPage() {
    // 旧代码（混乱）：
    // int newPage = m_currentPage + 1;  // 这是0-based？1-based？
    
    // 新代码（清晰）：
    ArrayIndex currentIdx(m_currentPage);
    ArrayIndex nextIdx = currentIdx.next();
    
    if (nextIdx.value() < m_pages.size()) {
        setCurrentPage(nextIdx);
    }
}

// ====== 示例2：计算全局页码 ======

GlobalPageNumber PageView::getCurrentGlobalPage() const {
    // 旧代码（易错）：
    // int global = m_globalStartPage + m_currentPage;  // 忘记+1？-1？
    
    // 新代码（类型安全）：
    using namespace PageNumberV2;
    
    ArrayIndex currentIdx(m_currentPage);
    PageNumber startPage(m_globalStartPage);
    int totalPages = GlobalPageManager::instance().getTotalGlobalPages();
    
    return arrayIndexToGlobal(currentIdx, startPage, totalPages);
}

// ====== 示例3：渲染页码 ======

void UnifiedPageRenderer::renderPageNumber(const GlobalPageNumber& global, const QString& format) {
    // 旧代码（需要手动格式化）：
    // QString text = format;
    // text.replace("{page}", QString::number(pageNum));  // pageNum是什么？
    // text.replace("{total}", QString::number(totalPages));
    
    // 新代码（一行搞定）：
    QString text = global.format(format);
    
    // 渲染...
}

// ====== 示例4：页码验证 ======

bool isValidNavigation(const GlobalPageNumber& target) {
    // 旧代码（手动检查）：
    // if (pageNum < 1 || pageNum > totalPages) return false;
    
    // 新代码（语义化）：
    return target.isValid() && target.hasNextPage();
}

*/

#endif // PAGENUMBER_V2_H

